package com.my.lambda;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

/**
 * @author zhupanlin
 * @version 1.0
 * @description: TODO
 * @date 2024/2/6 9:32
 */
public class StreamDemo {
    
    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    static class Person{
        private String name;
        private String gender;
        private Integer age;
    }

    public static void main(String[] args) {
        List<Person> list = List.of(
                new Person("zhang san", "男", 16),
                new Person("li si", "女", 20),
                new Person("zhao liu", "男", 22),
                new Person("wang wu", "男", 33),
                new Person("哈 得", "男", 55));
        
        // 1. 挑出年龄大于 18岁的人
        // filter、map、flatMap
        list.stream()
                .filter(person -> person.age > 18) // 挑出大于18 person流
                .peek(System.out::println)
                .map(person -> person.getName()) // 拿到所有人的姓名
                .flatMap(ele -> Arrays.stream(ele.split(" ")))
                .distinct()
                .forEach(System.out::println);
        
        
        // 
    }

    public static void A(String[] args) {
        
        //1.找出最大偶数
        List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        
        // for循环，挨个遍历找到偶数，temp = i; 下次找到的偶数和临时变量比较
        int max = 0;
        for (Integer integer : list) {
            if (integer % 2 == 0){
                // 是偶数，和max进行比较交换
                max = integer > max ? integer : max;
            }
        }
        System.out.println("最大偶数：" + max);
        
        // 流的特性
        // 1) 流是lazy的，不用方法就不会被调用
        // terminal operation 终止操作
        // intermediate operation 中间操作
        
        // 2. StreamAPI
        // 1) 把数据封装成流
        // 2) 定义流式操作
        // 3) 获得最终结果
        list.stream()
                .filter(ele -> {
                    System.out.println("正在filter：" + ele);
                    return ele % 2 == 0;
                })
                .max(Integer::compareTo)
                .ifPresent(System.out::println); // 过滤出我们想要的值，如果断言返回true就是我们要的
        
        // 流的三大部分：
        // 1.数据流    2.N个中间操作    3.一个终止操作
        /**
         * 1. 数据流
         *  1) 创建流  
         *  2) 直接从集合容器中获取这个流 List、Set、Map
         */
        Stream<Integer> stream = Stream.of(1, 2, 3);
        Stream<Integer> concat = Stream.concat(Stream.of(2, 3, 4), stream);
        Stream<Object> build = Stream.builder().add("11").add("22").build();


        List<Integer> integers = List.of(1, 2);
        Stream<Integer> stream1 = integers.stream();

        Set<Integer> integers1 = Set.of(1, 2);
        Stream<Integer> stream2 = integers1.stream();

        Map<Object, Object> of = Map.of();
        of.keySet().stream();
        of.entrySet().stream();

        System.out.println("主线程：" + Thread.currentThread());
        
        // 流是否并发 和for有啥区别？  流也是用for循环挨个处理，默认不并发，也可以并发
        // 并发以后，要自行解决多线程的安全问题
        
        // 有状态数据将产生并发安全问题。
        // 流的所有操作都是无状态；数据状态仅在此函数内有效，不溢出至函数外
        
        long count = Stream.of(1, 2, 3, 4, 5).
                parallel()  // intermediate operation，并发流
                .filter(i -> {
                    System.out.println("filter线程：" + Thread.currentThread());
                    System.out.println("正在filter：" + i);
                    return i > 2;
                })
                .count();

        System.out.println("count = " + count);
    }
    
}
